package com.kmxd.ams.app.event.efile.command;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.kmxd.ams.client.event.efile.EfileConvertEvent;
import com.kmxd.ams.client.oss.IEfileRecordSvc;
import com.kmxd.ams.client.oss.dto.EfileRecordQueryDTO;
import com.kmxd.ams.client.oss.vo.EfileRecordListVO;
import com.kmxd.ams.client.system.ISysConfigSvc;
import com.kmxd.ams.client.system.ISysFondsSvc;
import com.kmxd.ams.core.common.constant.ConfigConst;
import com.kmxd.ams.core.common.constant.Constants;
import com.kmxd.ams.core.common.constant.ErrorCode;
import com.kmxd.ams.core.common.enums.ArchStatusEnum;
import com.kmxd.ams.core.common.enums.DbTypeEnum;
import com.kmxd.ams.core.common.enums.TransferStatusEnum;
import com.kmxd.ams.core.config.AmsConfig;
import com.kmxd.ams.core.convert.DocConvertUtil;
import com.kmxd.ams.core.convert.impl.PdfService;
import com.kmxd.ams.core.exception.BizTipException;
import com.kmxd.ams.core.oss.template.OssTemplate;
import com.kmxd.ams.core.util.ConfigUtil;
import com.kmxd.ams.core.util.DynamicTableNameUtil;
import com.kmxd.ams.core.util.IdUtil;
import com.kmxd.ams.infra.arrange.base.BaseBO;
import com.kmxd.ams.infra.oss.entity.EfileRecord;
import com.kmxd.ams.infra.system.entity.SysFonds;
import com.kmxd.ams.infra.system.mapper.SysFondsMapper;
import java.io.File;
import java.util.Date;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * 电子文件转换
 *
 * @author ZuoLG
 */
@Slf4j
@Component
@AllArgsConstructor
public class EfileConvertCmd {
  private final SysFondsMapper sysFondsMapper;
  private IEfileRecordSvc efileSvc;
  private OssTemplate ossTemplate;
  private ISysConfigSvc sysConfigSvc;
  private ISysFondsSvc sysFondsSvc;
  private DocConvertUtil convertUtil;
  private AmsConfig amsConfig;

  /** 电子文件转换 */
  @Transactional(rollbackFor = Exception.class)
  public void efileConvert(EfileConvertEvent event) throws Exception {
    log.debug("docIds: {} ", event.getReq().toString());
    // 查询所有全宗，
    List<SysFonds> fondsList = sysFondsSvc.list();
    fondsList.forEach(
        fonds -> {
          try {
            fileOpt(event, fonds);
          } catch (Exception e) {
            log.error("文件格式转换失败", e);
            log.info("全宗:【{}】编码:【{}】不具备电子文件转换条件，请检查电子文件表！", fonds.getName(), fonds.getCode());
          }
        });
  }

  /**
   * 电子文件操作
   *
   * @param event
   */
  private void fileOpt(EfileConvertEvent event, SysFonds fonds) {
    // 获取转换的文件类型
    String fileTypeConf = sysConfigSvc.getConfigContentByKey(ConfigConst.OSS_FILE_TYPE);
    // 获取转换方式
    String transferConf = sysConfigSvc.getConfigContentByKey(ConfigConst.OSS_TRANSFER);
    // 转换后缀
    String transferExt = ConfigUtil.getVal(transferConf, ConfigConst.TRANSFER_EXT);
    // 转换方式
    String transferType = ConfigUtil.getVal(transferConf, ConfigConst.TRANSFER_TYPE);
    // 转换Url
    String transferURL = ConfigUtil.getVal(transferConf, ConfigConst.TRANSFER_URL);
    // 设置支持的格式
    if (ObjectUtil.isNotNull(fileTypeConf)) {
      List<String> words = ConfigUtil.getStrs(fileTypeConf, "word");
      List<String> excels = ConfigUtil.getStrs(fileTypeConf, "excel");
      List<String> ppts = ConfigUtil.getStrs(fileTypeConf, "ppt");
      List<String> pdfs = ConfigUtil.getStrs(fileTypeConf, "pdf");
      List<String> imgs = ConfigUtil.getStrs(fileTypeConf, "img");
      List<String> htmls = ConfigUtil.getStrs(fileTypeConf, "html");
      List<String> tiffs = ConfigUtil.getStrs(fileTypeConf, "tiff");
      convertUtil.init(transferType).setFileType(words, PdfService.TYPE_WORD);
      convertUtil.init(transferType).setFileType(excels, PdfService.TYPE_EXCEL);
      convertUtil.init(transferType).setFileType(ppts, PdfService.TYPE_PPT);
      convertUtil.init(transferType).setFileType(pdfs, PdfService.TYPE_PDF);
      convertUtil.init(transferType).setFileType(imgs, PdfService.TYPE_IMG);
      convertUtil.init(transferType).setFileType(htmls, PdfService.TYPE_HTML);
      convertUtil.init(transferType).setFileType(tiffs, PdfService.TYPE_TIFF);
    }
    String tableName = Constants.TABLE_NAME_EFILE + "_" + fonds.getAutoIndex();
    log.info("全宗:【{}】编码:【{}】电子文件表【{}】", fonds.getName(), fonds.getCode(), tableName);
    String tableSchema;
    int count = 0;
    if (StrUtil.isBlank(amsConfig.getDbType())
        || StrUtil.equals(DbTypeEnum.MYSQL.getCode(), amsConfig.getDbType())) {
      tableSchema = sysFondsMapper.getDataBaseId();
      count = sysFondsMapper.haveEfileTable(tableSchema, tableName);
    } else {
      tableSchema = amsConfig.getDbName();
      count = sysFondsMapper.haveEfileTablePG(tableSchema, tableName);
    }
    if (count == 0) {
      throw BizTipException.instance(
          ErrorCode.ARCHIVE_DATA_EXIST, StrUtil.format("电子文件表:[{}]不存在，跳过当前转换全宗!", tableName));
    }
    BaseBO req = event.getReq();
    List<EfileRecordListVO> efiles = Lists.newArrayList();
    // 如果事件中有需要处理的，就只处理指定部分，否则查询所有未转换的进行处理
    DynamicTableNameUtil.setTableName(tableName);
    if (StrUtil.isNotBlank(req.getDocIds())) {
      efiles =
          efileSvc.selectListByDocIds(
              req.getArchTypeId(), IdUtil.split(String.valueOf(req.getDocIds())));
    } else {
      EfileRecordQueryDTO queryDTO = new EfileRecordQueryDTO();
      // "装换状态：1待处理，2转换中，3成功，4失败，99不支持转换，0不需要转换"
      queryDTO.setTransferStatus(1L);
      Page page = new PageDTO(1, Constants.DEF_BATCH_PAGE_SIZE);
      efiles = efileSvc.selectPage(page, queryDTO).getRecords();
    }
    log.info(
        "全宗:【{}】编码:【{}】电子文件表【{}】需要转换的文件数量：{}",
        fonds.getName(),
        fonds.getCode(),
        tableName,
        efiles.size());
    List<EfileRecord> efileUpdate = com.google.common.collect.Lists.newArrayList();
    efiles.forEach(
        efile -> {
          try {
            String basePath =
                NumberUtil.equals(efile.getArrangeStatus(), ArchStatusEnum.S1.getCode())
                    ? ossTemplate.getManagePath(efile.getDefPath())
                    : ossTemplate.getCollectPath(efile.getDefPath());
            String srcPath =
                NumberUtil.equals(efile.getArrangeStatus(), ArchStatusEnum.S1.getCode())
                    ? ossTemplate.getManagePath(efile.getDefPath()) + efile.getPath()
                    : ossTemplate.getCollectPath(efile.getDefPath()) + efile.getPath();
            // 判断文件是否存在 "装换状态：1待处理，2转换中，3成功，4失败，99不支持转换，0不需要转换"
            efile.setTransferStatus(
                FileUtil.exist(srcPath)
                    ? TransferStatusEnum.S2.getCode()
                    : TransferStatusEnum.S4.getCode());

            // .需特殊处理
            String pdfPath =
                efile.getPath().substring(0, efile.getPath().lastIndexOf('.')) + "." + transferExt;

            efile.setShowExt(transferExt);
            efile.setShowFilePath(pdfPath);
            // 根据类型转换执行不同的转换,转换方式：aspose|shuke|youhong
            // 执行文件转换
            convertUtil.init(transferType).docConvert(srcPath, basePath + pdfPath);
            File pdfFile = FileUtil.file(basePath + pdfPath);
            // 提取页数
            efile.setFilePage(convertUtil.init(transferType).getFilePages(basePath + pdfPath));
            // 提取文件大小
            efile.setPdfSize(FileUtil.size(pdfFile));
            efile.setTransferStatus(TransferStatusEnum.S3.getCode());
            //添加档号章
            
          } catch (Exception e) {
            log.error(e.getMessage(), e);
            efile.setTransferStatus(TransferStatusEnum.S4.getCode());
            efile.setUpdateTime(new Date());
          }
          EfileRecord record = BeanUtil.copyProperties(efile, EfileRecord.class);
          efileUpdate.add(record);
        });
    if (efileUpdate.size() > 0) {
      efileSvc.updateBatchById(efileUpdate);
    }
  }
}
